#include "protocol.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "../online_user/online_user.h"

// 登录请求序列化（格式："account:password"）
char * protocol_serialize_login(LoginRequest * req)
{
    if(!req || !req->account || !req->password) return NULL;

    // 计算长度：account长度 + password长度 + 2（分隔符和结束符）
    size_t len = strlen(req->account) + strlen(req->password) + 2;
    char * buf = (char *)malloc(len);
    if(!buf) return NULL;

    snprintf(buf, len, "%s:%s", req->account, req->password);
    return buf;
}
char * protocol_serialize_register(RegisterRequest * req)
{
    if(!req || !req->name || !req->account || !req->password) return NULL;
    // 计算长度+两个分隔符和一个结束符
    size_t len = strlen(req->account) + strlen(req->password) + strlen(req->name) + 3;
    char * buf = (char *)malloc(len);
    if(!buf) return NULL;

    snprintf(buf, len, "%s:%s:%s", req->name, req->account, req->password);
    return buf;
}
// 登录响应反序列化（假设服务器返回格式："success,msg,user_id" 或 "fail,msg"）
bool protocol_deserialize_login(const char * data, LoginResponse * resp)
{
    if(!data || !resp) return false;
    resp->msg   = NULL;
    char * copy = strdup(data); // 复制一份避免修改原数据
    if(!copy) return false;

    // 解析第一个字段（success/fail）
    char * token = strtok(copy, ":");
    if(!token) {
        free(copy);
        return false;
    }
    resp->success = (strcmp(token, "success") == 0);

    // 解析第二个字段（msg）
    token = strtok(NULL, ":");
    if(token) {
        resp->msg = strdup(token);
        if(!resp->msg) { // 检查分配失败
            free(copy);
            return false;
        }
    } else {
        resp->msg = strdup("未知错误");
        if(!resp->msg) { // 检查分配失败
            free(copy);
            return false;
        }
    }

    // 解析第三个字段（user_id，仅success时有）
    if(resp->success) {
        token = strtok(NULL, ":");
        if(token) {
            resp->user_id = atoi(token);
        } else {
            resp->user_id = 0;
        }
    } else {
        resp->user_id = 0;
    }
    printf("解析数据接收\n");
    free(copy);
    return true;
}
// 注册响应，（返回格式："success，msg，user_id"或者"fail,msg"
bool protocol_deserialize_register(const char * data, RegisterResponse * resp)
{
    if(!data || !resp) return false;

    char * copy = strdup(data);
    if(!copy) return false;

    // 解析第一个字段（success、fail）
    char * token = strtok(copy, ":");
    if(!token) {
        free(copy);
        return false;
    }
    resp->success = (strcmp(token, "success") == 0);

    // 解析第二个字段
    token = strtok(NULL, ":");
    if(token) {
        resp->msg = strdup(token);
    } else {
        resp->msg = "未知错误";
    }
    if(resp->success) {
        token = strtok(NULL, ":");
        if(token) {
            resp->user_id = atoi(token);
        } else {
            resp->user_id = 0;
        }
    } else {
        resp->user_id = 0;
    }
    free(copy);
    return true;
}

bool protocol_parse_online_list(const char * data, OnlineUserList * list)
{
    if(!data || !list) return false;
    list->users = NULL;
    list->count = 0;
    // 传入的数据是 id：nickname，id：nickname.......
    char * copy = strdup(data); // strdup = malloc + strcpy,复制data，防止破坏原数据
    if(!copy) {
        printf("[ERROR] 内存分配失败，无法复制数据\n");
        return false; // 分配失败时必须处理
    } 
    // 使用strtok分割多个用户,后续用strtok(NULL,",")得到下一份用户
    char * token = strtok(copy, ",");
    while(token) {
        // 每个用户格式："ID:昵称"
        char * colon_pos = strchr(token, ':');
        if(!colon_pos) {
            printf("[PROTOCOL] 解析警告：用户数据格式错误（应为ID:昵称），跳过无效数据: %s\n", token);
            token = strtok(NULL, ","); // 继续下一个用户
            continue;
        }

        // 2. 计算ID和昵称的长度（避免修改原始字符串）
        size_t id_len   = colon_pos - token;     // 冒号前的字符数（ID长度）
        size_t nick_len = strlen(colon_pos + 1); // 冒号后的字符数（昵称长度）

        // 3. 检查ID和昵称有效性
        if(id_len == 0) {
            printf("[PROTOCOL] 解析警告：用户ID为空，跳过无效数据: %s\n", token);
            token = strtok(NULL, ",");
            continue;
        }
        if(nick_len == 0) {
            printf("[PROTOCOL] 解析警告：用户昵称为空，跳过无效数据: %s\n", token);
            token = strtok(NULL, ",");
            continue;
        }
        char id_str[32] = {0}; // 假设ID不超过31位
        strncpy(id_str, token, id_len);
        uint32_t user_id = atoi(id_str);

        // 5. 提取昵称（直接指向冒号后即可，无需复制）
        const char * nickname = colon_pos + 1;

        // 动态扩容用户列表
        list->users                       = realloc(list->users, (list->count + 1) * sizeof(OnlineUserData));
        list->users[list->count].user_id  = user_id;
        list->users[list->count].nickname = strdup(nickname); // 复制字符串
        list->count++;

        token = strtok(NULL, ",");
    }

    free(copy);
    return list->count > 0;
}

// 解析聊天消息（数据格式："11:发送者ID:发送者昵称:内容"）
bool protocol_parse_chat_msg(const char * data, ServerChatMsg * msg)
{
    if(!data || !msg) return false;
    msg->from_user_id  = 0;
    msg->from_nickname = NULL;
    msg->content       = NULL;

    // 跳过消息类型（如"11:"）
    char * type_end = strchr(data, ':');
    if(!type_end) return false;
    char * copy = strdup(type_end + 1);
    if(!copy) return false;

    // 解析发送者ID
    char * token = strtok(copy, ":");
    if(!token) {
        free(copy);
        return false;
    }
    msg->from_user_id = atoi(token);

    // 解析发送者昵称
    token = strtok(NULL, ":");
    if(!token) {
        free(copy);
        return false;
    }
    msg->from_nickname = strdup(token);

    // 解析消息内容
    token = strtok(NULL, "\0"); // 内容可能包含":"，取剩余全部
    if(!token) {
        free(copy);
        return false;
    }
    msg->content = strdup(token);

    free(copy);
    return true;
}

// 序列化客户端发送的聊天消息（格式："接收者ID:内容"）
char * protocol_serialize_chat_send(uint32_t to_user_id, const char * content)
{
    if(!content) return NULL;
    size_t len = snprintf(NULL, 0, "%u:%s", to_user_id, content) + 1;
    char * buf = malloc(len);
    snprintf(buf, len, "%u:%s", to_user_id, content);
    return buf;
}